﻿using CaseManagerLibrary.DB.SQLite;
using CaseManagerLibrary.Http;
using CaseManagerLibrary.Models;
using Newtonsoft.Json;
using PSDClientService.SystemSettings;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PSDClientService.Download
{
    public class ErrorFileManager
    {
        private DownloadContext context;
        private Thread errorFileThread = null;
        private SQLiteHelper sqlite;
        private SQLiteConnection conn;
        private static object lock_conn = new object();

        private bool paused = false;
        public bool Enabled { get; set; }
        public ErrorFileManager(DownloadContext ctx)
        {
            context = ctx;
        }

        public bool Init()
        {
            paused = false;

            string file = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "PSD", "Data", "errorfiles.db");

            Enabled = System.IO.File.Exists(file);

            if (Enabled)
            {
                sqlite = new SQLiteHelper();
                sqlite.FileName = file;

                //errorFileThread = new Thread(new ThreadStart(RetryErrorFile));
                //errorFileThread.Start();
            }

            return Enabled;
        }

        public void Pause()
        {
            paused = true;
        }

        public void Continue()
        {
            paused = false;
        }

        public void RetryErrorFile()
        {
            while (context.Running && Enabled)
            {
                if (context.Downloading && !paused)
                {
                    lock (lock_conn)
                    {
                        var conn = sqlite.Open();

                        if (conn != null)
                        {
                            try
                            {
                                string sql = "select * from error_files where state=2 order by video_start_time";

                                var files = sqlite.Query<error_files>(conn, sql, null);

                                foreach (var file in files)
                                {
                                    context.Logger.Info("重试下载文件：" + file.file_name);

                                    Dictionary<string, string> data = new Dictionary<string, string>();
                                    data.Add("fileId", file.file_id);

                                    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.ReDownloadFile, data);

                                    if (result.success)
                                    {
                                        file.state = 1;
                                        file.retry_time = DateTime.Now;
                                        sqlite.Update<error_files>(conn, file);

                                        context.Logger.Log("重试下载文件成功：" + file.file_name);
                                    }
                                    else
                                    {
                                        context.Logger.Error("重试下载文件失败：" + file.file_name + " Error：" + result.message);
                                    }
                                }

                                if (files.Count > 0)
                                {
                                    context.DownloadManager.GetDownloadWaitingFiles();
                                }
                            }
                            catch (Exception ex)
                            {
                                context.Logger.Error("RetryErrorFile Error：" + ex.Message);
                            }
                            finally
                            {
                                sqlite.Close(conn);
                            }
                        }
                    }
                }

                Thread.Sleep(1000 * 60 * 10);
            }
        }

        public void AddErrorFile(error_files file)
        {
            lock (lock_conn)
            {
                var conn = sqlite.Open();

                if (conn != null)
                {
                    try
                    {
                        file.id = sqlite.Insert<error_files>(conn, file);

                        context.Logger.Error("添加下载错误文件到重试队列：" + file.file_name);
                    }
                    catch (Exception ex)
                    {
                        context.Logger.Error("AddErrorFile Error：" + ex.Message);
                    }
                    finally
                    {
                        sqlite.Close(conn);
                    }
                }
            }
        }

        public void IngoreErrorFile(List<string> ignoreList)
        {
            lock (lock_conn)
            {
                var conn = sqlite.Open();

                if (conn != null)
                {
                    try
                    {
                        foreach (string fileId in ignoreList)
                        {
                            string sql = "select * from error_files where file_id='" + fileId + "'";

                            var files = sqlite.Query<error_files>(conn, sql, null);

                            foreach (var file in files)
                            {
                                file.state = 1;
                                file.retry_time = DateTime.Now;
                                sqlite.Update<error_files>(conn, file);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        context.Logger.Error("IngoreErrorFile Error：" + ex.Message);
                    }
                    finally
                    {
                        sqlite.Close(conn);

                    }
                }

                var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.IgnoreDownloadFail, JsonConvert.SerializeObject(ignoreList));
            }
        }

        public void Dispose()
        {
            Enabled = false;

            try
            {
                if (errorFileThread != null)
                {
                    errorFileThread.Abort();
                }
            }
            catch
            { }
        }
    }
}
